using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Random = UnityEngine.Random;

/// <summary>
/// 转盘功能
/// </summary>
public class TurntableGrid : MonoBehaviour
{
    int mGridNum = 5;
    
    [SerializeField] GridLayoutGroup mGridLayoutGroup;
    [SerializeField] private TurntableItem mItemPreset;

    private float gridSize;
    private float itemSize, itemSpace;

    private List<TurntableItem>[] sideItemGroup = new List<TurntableItem>[4]
    {
        new List<TurntableItem>(),
        new List<TurntableItem>(),
        new List<TurntableItem>(),
        new List<TurntableItem>()
    };
    private List<TurntableItem> sideItems = new List<TurntableItem>();

    
    private int curNumberIndex = 0;    //当前点亮的数字索引
    private int targetNumberIndex = 0; //转盘停止时的目标数字索引
    private int remainNumberIndex = 0; //倒计时个数
    private int[] frequencyLevels = new [] {20, 16, 12, 8, 4, 2}; // 转盘转动的频率等级
    private int curFrequencyLevel = 0; // 当前频率等级
    
    private TurntableItem curItem;

    private TimerMgr timer;
    private int timerID;
    private Action onTurntableFinished;
    
    /// <summary> 启动转盘 </summary>
    public void StartPlay(int targetNum, Action callback)
    {
        onTurntableFinished = callback;
        
        if (targetNum <= 0 || targetNum > sideItems.Count)
            targetNum = Random.Range(1, sideItems.Count);
    
        curNumberIndex = 0;
        curFrequencyLevel = 0;
        remainNumberIndex = 0;
        targetNumberIndex = targetNum;
        remainNumberIndex = targetNumberIndex;
    
        for (int i = 0; i < sideItems.Count; i++)
        {
            sideItems[i].RefreshItemAndNum(Color.white);
        }
    
        timerID = timer.Schedule(UpdateTurntable, 0, 1.0f / frequencyLevels[curFrequencyLevel]);
    }
    
    public int SideItemsCount => sideItems.Count;

    private void UpdateTurntable()
    {
        //重置上一个数字颜色
        if (null != curItem)
            curItem.RefreshItem(Color.white);
        
        //点亮当前数字
        HighlightNumber(curNumberIndex, Color.red);
        curNumberIndex++;
    
        if (curNumberIndex > sideItems.Count)
        {
            curNumberIndex = 0;
            curFrequencyLevel++;
    
            if (curFrequencyLevel >= frequencyLevels.Length - 1)
            {
                timer.Unschedule(timerID); //取消定时更新转盘
                timer.Schedule(LastTurntable, 0, 1.0f / frequencyLevels[curFrequencyLevel], remainNumberIndex); // 降低到每秒点亮2个数字
            }
            else
            {
                timer.Unschedule(timerID); //取消定时更新转盘
                timerID = timer.Schedule(UpdateTurntable, 0, 1.0f / frequencyLevels[curFrequencyLevel]);
            }
        }
    }

    private void LastTurntable()
    {
        if (null != curItem)
            curItem.RefreshItem(Color.white);

        HighlightNumber(curNumberIndex, Color.red);
        remainNumberIndex--;
        curNumberIndex++;
        if (remainNumberIndex <= 0)
        {
            StartCoroutine(ResetAllNumbersTo100()); //将所有数字设置为100
        }
    }

    private void HighlightNumber(int index, Color color)
    {
        if (index < sideItems.Count)
        {
            TurntableItem item = sideItems[index];
            if (null != item)
            {
                item.RefreshItem(color);
                curItem = item;
            }
        }
    }

    IEnumerator ResetAllNumbersTo100()
    {
        HighlightNumber(curNumberIndex-1, Color.green);
        
        yield return new WaitForSeconds(0.5f);
        
        foreach (TurntableItem item in sideItems)
        {
            item.ItemFinished();
        }
        
        onTurntableFinished?.Invoke();
    }

    private void Awake()
    {
        mItemPreset.gameObject.SetActive(false);
        Vector2 sizeDelta = mGridLayoutGroup.GetComponent<RectTransform>().sizeDelta;
        gridSize = sizeDelta.x;
        
        //初始化
        timer = new TimerMgr();
        timer.Init();
    }

    private void Update()
    {
        timer.Update();
    }

    /// <summary> 设置转盘 </summary>
    public void SetTurntableGrid(int gridNum)
    {
        mGridNum = gridNum;
        
        float delW = gridSize / mGridNum;
        itemSpace = delW * 0.1f;
        itemSize = delW - itemSpace;
        int padding = (int)(itemSpace * 0.5f);

        mGridLayoutGroup.padding = new RectOffset(padding, padding, padding, padding);
        mGridLayoutGroup.cellSize = new Vector2(itemSize, itemSize);
        mGridLayoutGroup.spacing = new Vector2(itemSpace, itemSpace);

        foreach (var itemList in sideItemGroup)
        {
            itemList.Clear();
        }
        sideItems.Clear();

        int gridNumMinusOne = mGridNum - 1;
        for (int i = 0; i < mGridNum; i++)
        {
            for (int j = 0; j < mGridNum; j++)
            {
                TurntableItem item = Instantiate(mItemPreset, this.transform);
                
                bool show = (i % gridNumMinusOne == 0 || j % gridNumMinusOne == 0);
                if (show)
                {
                    if (i == 0)
                        sideItemGroup[0].Add(item);
                    if (j == gridNumMinusOne)
                        sideItemGroup[1].Add(item);
                    if (i == gridNumMinusOne)
                        sideItemGroup[2].Add(item);
                    if (j == 0)
                        sideItemGroup[3].Add(item);
                }
                else
                    item.SetItem(false);
            }
        }

        int k = 0;
        for (int i = 0; i < sideItemGroup.Length; i++)
        {
            if (i > 1)
            {
                for (int j = sideItemGroup[i].Count-1; j >= 0; j--)
                {
                    AddItemToSideList(i, j, ref k);
                }
            }
            else
            {
                for (int j = 0; j < sideItemGroup[i].Count; j++)
                {
                    AddItemToSideList(i, j, ref k);
                }
            }
        }
    }
    
    void AddItemToSideList(int i, int j, ref int k)
    {
        if (!sideItems.Contains(sideItemGroup[i][j]))
        {
            k++;
            sideItemGroup[i][j].SetItem(true, k);
            sideItems.Add(sideItemGroup[i][j]);
        }
    }
}
